using Godot;


[Tool] // 允许编辑器实时预览
public partial class ChromaDoor : StaticBody2D
{



    [ExportGroup("Settings")]
    [Export]
    public Vector2 DoorSize
    {
        get => _doorSize;
        set { _doorSize = value; UpdateStructure(); }
    }
    private Vector2 _doorSize = new Vector2(32, 128);

    [Export]
    public DoorState CurrentState
    {
        get => _currentState;
        set
        {
            _currentState = value;
            if (Engine.IsEditorHint()) UpdateDoorState(true);
        }
    }
    private DoorState _currentState = DoorState.Closed;

    [ExportGroup("Internal Refs")]
    [Export] public CollisionShape2D Collider;
    [Export] public ColorRect VisualRect; // 修改引用类型为 ColorRect

    private Tween _tween;

    public override void _Ready()
    {
        // 强制确保材质独立
        if (VisualRect != null && VisualRect.Material is ShaderMaterial mat)
        {
            if (!mat.ResourceLocalToScene)
            {
                VisualRect.Material = (Material)mat.Duplicate();
            }
        }
        UpdateStructure();
        UpdateDoorState(true);
    }

    // 增加 Process 确保在编辑器里拖动大小时实时刷新
    public override void _Process(double delta)
    {
        if (Engine.IsEditorHint())
        {
            // 只有当参数变脏时才调用，或者简单粗暴每帧调用（性能开销极小）
            // 为了解决“拖动后不刷新”的问题，这里每帧同步 shader 参数
            SyncShaderParams();
        }
    }

    private void UpdateStructure()
    {
        // 1. 更新碰撞体
        if (Collider != null)
        {
            if (Collider.Shape == null || !Collider.Shape.IsLocalToScene())
                Collider.Shape = new RectangleShape2D();
            if (Collider.Shape is RectangleShape2D rect)
                rect.Size = _doorSize;
        }

        // 2. 更新视觉矩形 ColorRect
        if (VisualRect != null)
        {
            // 设置大小
            VisualRect.Size = _doorSize;

            // 关键：居中对齐
            // StaticBody 中心是 (0,0)，ColorRect 原点是左上角
            // 所以要往左上移动一半的距离
            VisualRect.Position = -_doorSize / 2.0f;

            // 同步 Shader 参数
            SyncShaderParams();
        }
    }

    private void SyncShaderParams()
    {
        if (VisualRect != null && VisualRect.Material is ShaderMaterial mat)
        {
            mat.SetShaderParameter("door_size", _doorSize);
        }
    }

    // --- 状态控制 (修改了动画对象) ---
    private void UpdateDoorState(bool instant)
    {
        if (Collider == null || VisualRect == null) return;

        // 目标缩放：Y轴
        float targetScaleY = (_currentState == DoorState.Open) ? 0.0f : 1.0f;
        float targetHeight = (_currentState == DoorState.Open) ? 0.0f : 1.0f;

        bool collisionDisabled = (_currentState == DoorState.Open);
        Collider.SetDeferred("disabled", collisionDisabled);

        // 获取材质
        ShaderMaterial mat = VisualRect.Material as ShaderMaterial;
        if (mat == null) return;

        // 杀掉旧动画
        if (_tween != null && _tween.IsValid()) _tween.Kill();

        if (instant)
        {
            // 瞬间设置参数
            mat.SetShaderParameter("open_height", targetHeight);
        }
        else
        {
            _tween = CreateTween();
            _tween.SetEase(Tween.EaseType.InOut).SetTrans(Tween.TransitionType.Quad);

            // 使用 TweenMethod 来平滑改变 Shader 参数
            _tween.TweenMethod(Callable.From<float>((val) =>
            {
                mat.SetShaderParameter("open_height", val);
            }),
            // 获取当前值作为起点 (防止动画跳变)
            (float)mat.GetShaderParameter("open_height"),
            targetHeight,
            0.5f); // 动画时长
        }
    }

    // --- 公共方法 ---
    public void SetOpenRequest(bool shouldOpen)
    {
        if (_currentState == DoorState.Disabled) return;

        var newState = shouldOpen ? DoorState.Open : DoorState.Closed;
        if (_currentState != newState)
        {
            _currentState = newState;
            UpdateDoorState(false); // 播放动画
        }
    }

    public void SetDisabled(bool disabled)
    {
        _currentState = disabled ? DoorState.Disabled : DoorState.Closed;
        UpdateDoorState(false);
    }

    public void ChangeState()
    {
        if (_currentState == DoorState.Disabled) return;

        if (_currentState == DoorState.Closed)
            _currentState = DoorState.Open;
        else if (_currentState == DoorState.Open)
            _currentState = DoorState.Closed;

        UpdateDoorState(false);
    }
}